package com.csl.jsonpreference.configdes

import android.text.TextUtils
import com.csl.jsonpreference.bean.ConfigTYPE
import com.csl.jsonpreference.tag.JsonConfig
import com.csl.jsonpreference.util.CLog
import org.json.JSONArray
import org.json.JSONObject


/**
 * json array类型
 */
open class JsonArrayPreference : JsonConfigIns {

    var jsonData: JSONArray

    //列表类型
    var arrayClassType: Class<*>? = null

    //item类型
    var itemDefaultClassType: Class<*> = String::class.java

    /** 数据描述*/
    var paramDesMap: ArrayList<JsonConfigIns> = ArrayList()

    /** 列表默认类型*/
    var defaultJsonConfigIns: JsonConfigIns = JsonConfigIns(
        key = "", title = "", discribe = "", ConfigTYPE.TXT
    )

    constructor(
        jsonData: JSONArray,
        classType: Class<*>? = null,
        jsonConfig: JsonConfigIns? = null,
    ) : super(jsonConfig ?: JsonConfigIns("", "", "", ConfigTYPE.AUTO)) {
        this.jsonData = jsonData
        this.arrayClassType = classType
        when (configType) {
            ConfigTYPE.ARRAY_OBJECT,
//            ConfigTYPE.ARRAY_TXT,
            ConfigTYPE.AUTO,
//            ConfigTYPE.ARRAY_BOOLEAN,
//            ConfigTYPE.ARRAY_FLOAT
            -> {
                autoSetType(jsonData, classType, jsonConfig)
            }

            else -> {}
        }

        CLog.d("initjson_array", "jsongroup 信息:" + key + "->" + describe)
    }

    /**
     * 自动判断类型
     *
     */
    fun autoSetType(
        jsonArray: JSONArray? = null,
        classType: Class<*>? = null,
        jsonConfig: JsonConfigIns?
    ) {
        configType = ConfigTYPE.ARRAY_OBJECT
        CLog.d(
            "initjson_array",
            "自动设置jsonarray json:$jsonArray, class:$classType, config:$jsonConfig"
        )
        //默认arraylist类型
        arrayClassType = ArrayList::class.java
        itemDefaultClassType = String::class.java
        paramDesMap.clear()

        var objClassConfig: JsonConfigIns? = null
        //存在配置表
        if (classType != null) {
            //获取item类型.  配置表情况下, 只允许相同类型
            var aType: Class<*>? = null
            if (classType.isArray) {
                //Array类型
                aType = classType.componentType
            } else if (jsonConfig != null) {
                //fixme list因为泛型类型擦除无法获取具体类型, 故需要强制使用注解传入的
                aType = jsonConfig.listType
            }
            CLog.d("initjson_array", "解析jsonarray类型:" + aType)
            var aTypeConfig = aType?.getAnnotation(JsonConfig::class.java)

            if (aType != null) {
                itemDefaultClassType = aType
//                objJsonConfig = aType.getAnnotation(JsonConfig::class.java)?.let {
//                    CLog.d("jsonarray", "读取到的类型注解:" + it)
//                    JsonConfigIns(it)
//                }
                if(aTypeConfig != null) {
                    //标注了类型, obj类型
                    var itemJsonConfig = JsonConfigIns(aTypeConfig)
                    itemJsonConfig.configType = ConfigTYPE.AUTO
                    if (!TextUtils.isEmpty(jsonConfig?.title)) {
                        itemJsonConfig.title = jsonConfig?.title!!
                    }

                    defaultJsonConfigIns = JsonObjectPreference(
                        JSONObject(),
                        aType,
                        itemJsonConfig
                    )
                    CLog.d("initjson_array", "解析类型:" + itemJsonConfig)
                    CLog.d(
                        "initjson_array",
                        "最终类型:" + defaultJsonConfigIns as JsonObjectPreference
                    )
                    objClassConfig = defaultJsonConfigIns
                } else {
                    //基础类型
                    defaultJsonConfigIns = when (aType) {
                        Double::class.java, java.lang.Double::class.java -> {
                            JsonConfigIns(
                                key = "", title = "", discribe = "", ConfigTYPE.FLOAT
                            )
                        }
                        Int::class.java, Integer::class.java, Long::class.java, java.lang.Long::class.java -> {
                            JsonConfigIns(
                                key = "", title = "", discribe = "", ConfigTYPE.NUMBER
                            )

                        }
                        Boolean::class.java, java.lang.Boolean::class.java -> {
                            JsonConfigIns(
                                key = "", title = "", discribe = "", ConfigTYPE.BOOLEAN
                            )
                        }
                        else -> {
                            JsonConfigIns(key = "", title = "", discribe = "", ConfigTYPE.TXT)
                        }
                    }
                    objClassConfig = defaultJsonConfigIns
                }
            }
        }
        //json里存在, 配置表不存在时
        if (jsonArray != null && jsonArray.length() > 0) {
            for (i in 0 until jsonArray.length()) {
                var jsonItem = jsonArray.get(i)
                var itemType = jsonItem.javaClass
                if (objClassConfig == null) {
                    //没指定类型时, 允许数组内类型不同
                    var jsonItemClassConfig = when (itemType) {
                        Double::class.java, java.lang.Double::class.java -> {
                            JsonConfigIns(
                                key = "", title = "", discribe = "", ConfigTYPE.FLOAT
                            )

                        }

                        Int::class.java, Integer::class.java, Long::class.java, java.lang.Long::class.java -> {
                            JsonConfigIns(
                                key = "", title = "", discribe = "", ConfigTYPE.NUMBER
                            )

                        }

                        Boolean::class.java, java.lang.Boolean::class.java -> {
                            JsonConfigIns(
                                key = "", title = "", discribe = "", ConfigTYPE.BOOLEAN
                            )

                        }

                        JSONObject::class.java -> {
                            val objPreference = JsonObjectPreference(
                                jsonItem as JSONObject,
                                null,
                                JsonConfigIns(
                                    "",
                                    "",
                                    "",
                                    ConfigTYPE.OBJECT
                                )
                            )
                            objPreference.jsonData = jsonItem
                            objPreference
                        }

                        JSONArray::class.java -> {
                            val objPreference = JsonArrayPreference(
                                jsonItem as JSONArray,
                                null,
                                JsonConfigIns(
                                    "",
                                    "",
                                    "",
                                    ConfigTYPE.ARRAY_OBJECT
                                )
                            )
                            objPreference.jsonData = jsonItem
                            objPreference

                        }

                        else -> {
                            JsonConfigIns(key = "", title = "", discribe = "", ConfigTYPE.TXT)
                        }
                    }
                    paramDesMap.add(i, jsonItemClassConfig)
                } else {
                    var newItem = createNewItem()
                    //绑定item对应的json数据
                    when(newItem) {
                        is JsonObjectPreference -> {
                            newItem.jsonData = if(jsonItem is JSONObject) {
                                jsonItem
                            } else {
                                JSONObject().apply {
                                    jsonArray.put(i, this)
                                }
                            }
                        }
                        is JsonArrayPreference -> {
                            newItem.jsonData = if(jsonItem is JSONArray) {
                                jsonItem
                            } else {
                                JSONArray().apply {
                                    jsonArray.put(i, this)
                                }
                            }
                        }
                    }
                    CLog.d("addjson", "添加json类型(${newItem?.javaClass}):" + newItem)
                    paramDesMap.add(i, newItem)
                }
//                    configType =
            }
        }
        paramDesMap.sortBy {
            it.index
        }
//        objJsonConfig?.let {
//            defaultJsonConfigIns = objJsonConfig
//        }

        CLog.d("initjson_array", "自动类型判断结果 $this")

    }


//    fun getParamsList(): ArrayList<JsonConfigIns> {
////        var result = ArrayList<JsonConfigIns>()
////        result.addAll(paramDesMap)
////        result.sortBy {
////            it.index
////        }
////        return result
//        return paramDesMap
//    }


    /**
     * 创建一个新元素(没添加到json中)
     */
    fun createNewItem(): JsonConfigIns {
        if (defaultJsonConfigIns == null) {
            return JsonConfigIns(
                key = "", title = "", discribe = "", ConfigTYPE.TXT
            )
        }
        return if (defaultJsonConfigIns is JsonObjectPreference) {
            JsonObjectPreference(
                JSONObject(),
                itemDefaultClassType,
                defaultJsonConfigIns
            )
        } else if (defaultJsonConfigIns is JsonArrayPreference) {
            JsonArrayPreference(
                JSONArray(),
                itemDefaultClassType,
                defaultJsonConfigIns
            )
        } else {
            JsonConfigIns(
                defaultJsonConfigIns
            )
        }

    }

    /**
     * 将新元素添加到列表中
     */
    fun addNewItem(config: JsonConfigIns) {
        paramDesMap.add(config)
        when (config) {
            is JsonObjectPreference -> {
                jsonData.put(config.jsonData)
            }

            is JsonArrayPreference -> {
                jsonData.put(config.jsonData)
            }

            else -> {
                //字符串, 不用修改
            }
        }
    }

    fun removeItem(index: Int) {
        paramDesMap.removeAt(index)
        jsonData.remove(index)
    }


    override fun toString(): String {
        return "JsonArrayPreference(jsonData=$jsonData, arrayClassType=$arrayClassType, itemClassType=$itemDefaultClassType)"
    }


}